home *** CD-ROM | disk | FTP | other *** search
/ Greenhouse Effect Detection Expriment / NASA Greenhouse Effect Detection Expriment 1992 - Disc 2.iso / software / dos / cdf22pc / src / tools / cdfstats.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-04  |  16.2 KB  |  593 lines

  1. /******************************************************************************
  2. *
  3. *  NSSDC/CDF                        CDFstats (statistics).
  4. *
  5. *  Version 2.0, 4-Mar-92, ST Systems (STX)
  6. *
  7. *  Modification history:
  8. *
  9. *   V1.0  10-Apr-91, J Love    Original version.
  10. *   V1.1  25-Jun-91, J Love    CDF_EPOCH added as a data type.  Added QOP.
  11. *                Added PageInst.
  12. *   V1.2   1-Aug-91, J Love    TRUE/FALSE.  Added range checking.  Added
  13. *                EPOCH display.  Use 'Exit'/'ExitBAD'.  Use
  14. *                'CDFlib'.  Added min/max checking within the
  15. *                valid range.  Added output option.
  16. *   V2.0   4-Mar-92, J Love    Fixed online instructions.  Broke into smaller
  17. *                pieces for IBM-PC port.  Changes for IBM-RS6000
  18. *                port.  Added option to filter out fill values.
  19. *
  20. ******************************************************************************/
  21.  
  22. #include "cdfdist.h"
  23.  
  24. #define CDFSTATS       /* Define this in only one source file for CDFstats
  25.                and it must be before 'cdfstats.h' is included. */
  26. #include "cdfstats.h"
  27.  
  28. /******************************************************************************
  29. * Online help.
  30. ******************************************************************************/
  31.  
  32. static char *instructions[] = {
  33. #if defined(vms)
  34. "Usage:         $ CDFSTATS [/[NO]RANGE] [/[NO]FILL] [/OUTPUT=<file-path>]",
  35. "                          <cdf-path>",
  36. #endif
  37. #if defined(unix)
  38. "Usage:         % cdfstats [-[no]range] [-[no]fill] [-output <file-path>]",
  39. "                          <cdf-path>",
  40. #endif
  41. #if defined(__MSDOS__)
  42. "Usage:         > cdfstats [-[no]range] [-[no]fill] [-output <file-path>]",
  43. "                          <cdf-path>",
  44. #endif
  45. "",
  46. "Purpose:       CDFstats displays statistics about the variables in a CDF.",
  47. "               These include the minimum and maximum values and whether",
  48. "               or not the variable is monotonic.",
  49. "",
  50. "Parameter(s):  <cdf-path>",
  51. "                  The pathname of the CDF to check (do not enter an",
  52. "                  extension).",
  53. "",
  54. #if defined(vms)
  55. "Qualifier(s):  /[NO]RANGE",
  56. #endif
  57. #if defined(unix) | defined(__MSDOS__)
  58. "Qualifier(s):  -[no]range",
  59. #endif
  60. "                  Specifies whether or not range checking will be performed",
  61. "                  (using the VALIDMIN/VALIDMAX attributes if they exist).",
  62. #if NSSDC_STANDARD
  63. "                  The default is range checking on.",
  64. #else
  65. "                  The default is range checking off.",
  66. #endif
  67. "",
  68. #if defined(vms)
  69. "Qualifier(s):  /[NO]FILL",
  70. #endif
  71. #if defined(unix) | defined(__MSDOS__)
  72. "Qualifier(s):  -[no]fill",
  73. #endif
  74. "                  Specifies whether or not fill values will be filtered",
  75. "                  out when collecting statistics (using the FILLVAL",
  76. "                  attribute if it exists).  Fill values are filtered out",
  77. "                  by default.",
  78. #if NSSDC_STANDARD
  79. "                  attribute if it exists).  Fill values are filtered out",
  80. "                  by default.",
  81. #else
  82. "                  attribute if it exists).  Fill values are not filtered",
  83. "                  out by default.",
  84. #endif
  85. "",
  86. #if defined(vms)
  87. "               /OUTPUT=<file-path>",
  88. "                  Redirects the output to a file.  The file created will",
  89. "                  be named <file-path> (if <file-path> does not have an",
  90. "                  extension, `.STS' is appended automatically).  If /OUTPUT",
  91. "                  is not specified, the output is displayed at the terminal.",
  92. #endif
  93. #if defined(unix) | defined(__MSDOS__)
  94. "               -output <file-path>",
  95. "                  Redirects the output to a file.  The file created will",
  96. "                  be named <file-path> (if <file-path> does not have an",
  97. "                  extension, `.sts' is appended automatically).  If /OUTPUT",
  98. "                  is not specified, the output is displayed at the terminal.",
  99. #endif
  100. "",
  101. #if defined(vms)
  102. "Example(s):    $ CDFSTATS/NORANGE/NOFILL GISS_SOIL",
  103. "               $ CDFSTATS/OUTPUT=TEMPLATE3 CDF$SMPL:TEMPLATE3",
  104. #endif
  105. #if defined(unix)
  106. "Example(s):    % cdfstats -norange -nofill giss_soil",
  107. "               % cdfstats -output template3 ../../samples/template3",
  108. #endif
  109. #if defined(__MSDOS__)
  110. "Example(s):    > cdfstats gisswetl",
  111. "               > cdfstats -norange -nofill a:\\gisssoil",
  112. "               > cdfstats -output tplate3 ..\\..\\samples\\tplate3",
  113. #endif
  114. NULL };
  115.  
  116. /******************************************************************************
  117. * ConvertDataType.
  118. ******************************************************************************/
  119.  
  120. #define CONVERT(Type1,dataType2,ptr1,ptr2) { \
  121. switch (dataType2) { \
  122.   case CDF_BYTE: \
  123.   case CDF_INT1: \
  124.     *((Schar *) ptr2) = *((Type1 *) ptr1); \
  125.     break; \
  126.   case CDF_UINT1: \
  127.     *((Uchar *) ptr2) = *((Type1 *) ptr1); \
  128.     break; \
  129.   case CDF_INT2: \
  130.     *((short *) ptr2) = *((Type1 *) ptr1); \
  131.     break; \
  132.   case CDF_UINT2: \
  133.     *((unsigned short *) ptr2) = *((Type1 *) ptr1); \
  134.     break; \
  135.   case CDF_INT4: \
  136.     *((long *) ptr2) = *((Type1 *) ptr1); \
  137.     break; \
  138.   case CDF_UINT4: \
  139.     *((unsigned long *) ptr2) = *((Type1 *) ptr1); \
  140.     break; \
  141.   case CDF_FLOAT: \
  142.   case CDF_REAL4: \
  143.     *((float *) ptr2) = *((Type1 *) ptr1); \
  144.     break; \
  145.   case CDF_EPOCH: \
  146.   case CDF_DOUBLE: \
  147.   case CDF_REAL8: \
  148.     *((double *) ptr2) = *((Type1 *) ptr1); \
  149.     break; \
  150.   case CDF_CHAR: \
  151.   case CDF_UCHAR: \
  152.     /* Do nothing for now. */ \
  153.     break; \
  154. } \
  155. }
  156.  
  157. void ConvertDataType (dataType1, numElems1, dataType2, numElems2, ptr1, ptr2)
  158. long dataType1, numElems1, dataType2, numElems2;
  159. void *ptr1, *ptr2;
  160. {
  161. size_t len;
  162. int i;
  163. switch (dataType1) {
  164.   case CDF_BYTE:
  165.   case CDF_INT1:
  166.     CONVERT (Schar, dataType2, ptr1, ptr2);
  167.     break;
  168.   case CDF_UINT1:
  169.     CONVERT (Uchar, dataType2, ptr1, ptr2);
  170.     break;
  171.   case CDF_INT2:
  172.     CONVERT (short, dataType2, ptr1, ptr2);
  173.     break;
  174.   case CDF_UINT2:
  175.     CONVERT (unsigned short, dataType2, ptr1, ptr2);
  176.     break;
  177.   case CDF_INT4:
  178.     CONVERT (long, dataType2, ptr1, ptr2);
  179.     break;
  180.   case CDF_UINT4:
  181.     CONVERT (unsigned long, dataType2, ptr1, ptr2);
  182.     break;
  183.   case CDF_FLOAT:
  184.   case CDF_REAL4:
  185.     CONVERT (float, dataType2, ptr1, ptr2);
  186.     break;
  187.   case CDF_EPOCH:
  188.   case CDF_DOUBLE:
  189.   case CDF_REAL8:
  190.     CONVERT (double, dataType2, ptr1, ptr2);
  191.     break;
  192.   case CDF_CHAR:
  193.   case CDF_UCHAR:
  194.     if (dataType2 == CDF_CHAR || dataType2 == CDF_UCHAR) {
  195.       len = (numElems1 < numElems2 ? numElems1 : numElems2);
  196.       memmove (ptr2, ptr1, len);
  197.       for (i = len; i < numElems2; i++) *((Byte *) ptr2) = ' ';
  198.     }
  199.     break;
  200. }
  201. return;
  202. }
  203.  
  204. /******************************************************************************
  205. * CDFstats (MAIN).
  206. ******************************************************************************/
  207.  
  208. #if defined(vms)
  209. main (argc, argv)
  210. #else
  211. void main (argc, argv)
  212. #endif
  213. int argc;
  214. char *argv[];
  215. {
  216. CDFstatus status;
  217. char oSpec[MAX_PATH_LEN+1];
  218. char oDir[MAX_DIR_LEN+1];
  219. char oName[MAX_NAME_LEN+1];
  220. long recVary;
  221. long dimVarys[CDF_MAX_DIMS];
  222. long dataTypeE;                /* data type for attribute entry */
  223. long numElemsE;                /* number of elements for attribute
  224.                        entry */
  225. long maxRec;
  226. long varMaxRec;
  227. long numVars;
  228. long varN;                /* variable number */
  229. long NrecValues;            /* number of values per record */
  230. long numDims;
  231. long dimSizes[CDF_MAX_DIMS];
  232. long indices[CDF_MAX_DIMS];
  233. long counts[CDF_MAX_DIMS];
  234. long intervals[CDF_MAX_DIMS];
  235. char varName[CDF_VAR_NAME_LEN+1];
  236. char CDFpath[CDF_PATHNAME_LEN+1];
  237. long i;
  238. long varyCount;
  239. long count;
  240. long validminAttrN;            /* attribute number */
  241. long validmaxAttrN;            /* attribute number */
  242. long fillvalAttrN;
  243. void *temp;
  244. char delim;
  245.  
  246. QOP *qop;
  247. static char *validQuals[] = { "range", "norange", "output",
  248.                   "fill", "nofill", NULL };
  249. static int optRequired[] = { FALSE, FALSE, TRUE,
  250.                  FALSE, FALSE, 0 };
  251.  
  252. /******************************************************************************
  253. * Get qualifiers/options/parameters.
  254. ******************************************************************************/
  255.  
  256. switch (argc == 1) {
  257.   case 1:
  258.     PageInst (instructions);
  259.     Exit;
  260.   default:
  261.     qop = Qop (argc, argv, validQuals, optRequired);
  262.     if (qop == NULL) ExitBAD;
  263.  
  264.     /**************************************************************************
  265.     * Get CDF path parameter.
  266.     **************************************************************************/
  267.  
  268.     if (qop->Nparms < 1) {
  269.       printf ("Missing parameters.\n");
  270.       ExitBAD;
  271.     }
  272.     else
  273.       strcpy (CDFpath, qop->parms[0]);
  274.  
  275.     /**************************************************************************
  276.     * Check for /[NO]RANGE,-[no]range qualifier.
  277.     **************************************************************************/
  278.  
  279.     count = 0;
  280.     if (qop->qualEntered[0]) count++;
  281.     if (qop->qualEntered[1]) count++;
  282.  
  283.     switch (count) {
  284.       case 0:
  285. #if NSSDC_STANDARD
  286.     rangeCheck = TRUE;
  287. #else
  288.     rangeCheck = FALSE;
  289. #endif
  290.     break;
  291.       case 1:
  292.     if (qop->qualEntered[0])
  293.       rangeCheck = TRUE;
  294.     else
  295.       rangeCheck = FALSE;
  296.     break;
  297.       case 2:
  298.     printf ("Conflicting qualifiers.\n");
  299.     ExitBAD;
  300.     }
  301.  
  302.     /**************************************************************************
  303.     * Check for /OUTPUT,-output qualifier.
  304.     **************************************************************************/
  305.  
  306.     if (qop->qualEntered[2]) {
  307.       strcpy (oSpec, qop->qualOpt[2]);
  308.       ParsePath (oSpec, oDir, oName);
  309.       if (strchr(oName,'.') == NULL) strcat (oSpec, ".sts");
  310.       OUTfp = fopen (oSpec, "w");
  311.       if (OUTfp == NULL) {
  312.     printf ("Unable to open output file (%s).", oSpec);
  313.     ExitBAD;
  314.       }
  315.     }
  316.     else
  317.       OUTfp = stdout;
  318.  
  319.     /**************************************************************************
  320.     * Check for /[NO]FILL,-[no]fill qualifier.
  321.     **************************************************************************/
  322.  
  323.     count = 0;
  324.     if (qop->qualEntered[3]) count++;
  325.     if (qop->qualEntered[4]) count++;
  326.  
  327.     switch (count) {
  328.       case 0:
  329. #if NSSDC_STANDARD
  330.     filterFills = TRUE;
  331. #else
  332.     filterFills = FALSE;
  333. #endif
  334.     break;
  335.       case 1:
  336.     if (qop->qualEntered[3])
  337.       filterFills = TRUE;
  338.     else
  339.       filterFills = FALSE;
  340.     break;
  341.       case 2:
  342.     printf ("Conflicting qualifiers.\n");
  343.     ExitBAD;
  344.     }
  345.  
  346.     break;
  347. }
  348.  
  349. /******************************************************************************
  350. * Open CDF.
  351. ******************************************************************************/
  352.  
  353. status = CDFlib (OPEN_, CDF_, CDFpath, &id,
  354.          GET_, CDF_NUMDIMS_, &numDims,
  355.                CDF_DIMSIZES_, dimSizes,
  356.                CDF_NUMVARS_, &numVars,
  357.                CDF_MAXREC_, &maxRec,
  358.          NULL_);
  359. CHECKstatus (status);
  360.  
  361. if (maxRec == -1) {
  362.   fprintf (OUTfp, "There are no records in the CDF.\n");
  363.   CDFlib (SELECT_, CDF_, id,
  364.       CLOSE_, CDF_,
  365.       NULL_);
  366.   Exit;
  367. }
  368.  
  369. if (numVars == 0) {
  370.   fprintf (OUTfp, "There are no variables in the CDF.\n");
  371.   CDFlib (SELECT_, CDF_, id,
  372.       CLOSE_, CDF_,
  373.       NULL_);
  374.   Exit;
  375. }
  376.  
  377. for (i = 0; i < numDims; i++) {
  378.    indices[i] = 0;
  379.    intervals[i] = 1;
  380. }
  381.  
  382. status = CDFlib (SELECT_, CDF_, id,
  383.               CDF_RECCOUNT_, (long) 1,
  384.               CDF_RECINTERVAL_, (long) 1,
  385.               CDF_DIMINDICES_, indices,
  386.               CDF_DIMINTERVALS_, intervals,
  387.          NULL_);
  388. CHECKstatus (status);
  389.  
  390. if (rangeCheck) {
  391.   status = CDFlib (SELECT_, CDF_, id,
  392.            GET_, ATTR_NUMBER_, "VALIDMIN", &validminAttrN,
  393.              ATTR_NUMBER_, "VALIDMAX", &validmaxAttrN,
  394.            NULL_);
  395.   if (status == NO_SUCH_ATTR)
  396.     rangeCheck = FALSE;
  397.   else
  398.     CHECKstatus (status);
  399. }
  400.  
  401. if (filterFills) {
  402.   status = CDFlib (SELECT_, CDF_, id,
  403.            GET_, ATTR_NUMBER_, "FILLVAL", &fillvalAttrN,
  404.            NULL_);
  405.   if (status == NO_SUCH_ATTR)
  406.     filterFills = FALSE;
  407.   else
  408.     CHECKstatus (status);
  409. }
  410.  
  411. /******************************************************************************
  412. * Determine statistics for each variable.
  413. ******************************************************************************/
  414.  
  415. for (varN = 0; varN < numVars; varN++) {
  416.    status = CDFlib (SELECT_, CDF_, id,
  417.                  VAR_, varN,
  418.             GET_, VAR_NAME_, varName,
  419.               VAR_DATATYPE_, &dataTypeV,
  420.               VAR_NUMELEMS_, &numElemsV,
  421.               VAR_RECVARY_, &recVary,
  422.               VAR_DIMVARYS_, dimVarys,
  423.             NULL_);
  424.    CHECKstatus (status);
  425.  
  426.    fprintf (OUTfp, "\n");
  427.    fprintf (OUTfp, "\n");
  428.    delim = PickDelim (varName);
  429.    fprintf (OUTfp, "%3ld.  %c%s%c  ", varN + 1, delim, varName, delim);
  430.    fprintf (OUTfp, " %s/", TFvarianceToken(recVary));
  431.    for (i = 0; i < numDims; i++)
  432.       fprintf (OUTfp, "%s", TFvarianceToken(dimVarys[i]));
  433.    fprintf (OUTfp, "   (%s)", DataTypeToken(dataTypeV));
  434.    fprintf (OUTfp, "\n");
  435.    fprintf (OUTfp, "\n");
  436.  
  437.    if (rangeCheck) {
  438.      rangeCheckVar = TRUE;
  439.  
  440.      status = CDFlib (SELECT_, CDF_, id,
  441.                    ATTR_, validminAttrN,
  442.                    ENTRY_, varN,
  443.               NULL_);
  444.      if (status == NO_SUCH_ENTRY)
  445.        rangeCheckVar = FALSE;
  446.      else {
  447.        CHECKstatus (status);
  448.        MALLOC (validmin, ElemSize(dataTypeV) * numElemsV);
  449.        status = CDFlib (SELECT_, CDF_, id,
  450.             GET_, ENTRY_DATATYPE_, &dataTypeE,
  451.                   ENTRY_NUMELEMS_, &numElemsE,
  452.             NULL_);
  453.        CHECKstatus (status);
  454.        MALLOC (temp, ElemSize(dataTypeE) * numElemsE);
  455.        status = CDFlib (SELECT_, CDF_, id,
  456.             GET_, ENTRY_DATA_, temp,
  457.             NULL_);
  458.        CHECKstatus (status);
  459.        ConvertDataType (dataTypeE, numElemsE, dataTypeV, numElemsV,
  460.             temp, validmin);
  461.        free (temp);
  462.  
  463.        status = CDFlib (SELECT_, CDF_, id,
  464.                  ATTR_, validmaxAttrN,
  465.                  ENTRY_, varN,
  466.             NULL_);
  467.        if (status == NO_SUCH_ENTRY) {
  468.          rangeCheckVar = FALSE;
  469.          free (validmin);
  470.        }
  471.        else {
  472.          CHECKstatus (status);
  473.          MALLOC (validmax, ElemSize(dataTypeV) * numElemsV);
  474.      status = CDFlib (SELECT_, CDF_, id,
  475.               GET_, ENTRY_DATATYPE_, &dataTypeE,
  476.                 ENTRY_NUMELEMS_, &numElemsE,
  477.               NULL_);
  478.      CHECKstatus (status);
  479.      MALLOC (temp, ElemSize(dataTypeE) * numElemsE);
  480.          status = CDFlib (SELECT_, CDF_, id,
  481.               GET_, ENTRY_DATA_, temp,
  482.               NULL_);
  483.          CHECKstatus (status);
  484.      ConvertDataType (dataTypeE, numElemsE, dataTypeV, numElemsV,
  485.               temp, validmax);
  486.      free (temp);
  487.        }
  488.      }
  489.    }
  490.    else
  491.      rangeCheckVar = FALSE;
  492.  
  493.    if (filterFills) {
  494.      filterFillsVar = TRUE;
  495.  
  496.      status = CDFlib (SELECT_, CDF_, id,
  497.                    ATTR_, fillvalAttrN,
  498.                    ENTRY_, varN,
  499.               NULL_);
  500.      if (status == NO_SUCH_ENTRY)
  501.        filterFillsVar = FALSE;
  502.      else {
  503.        CHECKstatus (status);
  504.        MALLOC (fillval, ElemSize(dataTypeV) * numElemsV);
  505.        status = CDFlib (SELECT_, CDF_, id,
  506.             GET_, ENTRY_DATATYPE_, &dataTypeE,
  507.                   ENTRY_NUMELEMS_, &numElemsE,
  508.             NULL_);
  509.        CHECKstatus (status);
  510.        MALLOC (temp, ElemSize(dataTypeE) * numElemsE);
  511.        status = CDFlib (SELECT_, CDF_, id,
  512.             GET_, ENTRY_DATA_, temp,
  513.             NULL_);
  514.        CHECKstatus (status);
  515.        ConvertDataType (dataTypeE, numElemsE, dataTypeV, numElemsV,
  516.             temp, fillval);
  517.        free (temp);
  518.      }
  519.    }
  520.    else
  521.      filterFillsVar = FALSE;
  522.  
  523.    /***************************************************************************
  524.    * Determine how to read records.
  525.    ***************************************************************************/
  526.  
  527.    NrecValues = 1;
  528.  
  529.    for (i = 0; i < numDims; i++) {
  530.       if (dimVarys[i]) {
  531.     NrecValues *= dimSizes[i];
  532.     counts[i] = dimSizes[i];
  533.       }
  534.       else {
  535.     counts[i] = 1;
  536.       }
  537.    }
  538.  
  539.    if (recVary)
  540.      varMaxRec = maxRec;
  541.    else
  542.      varMaxRec = 0;
  543.  
  544.    /***************************************************************************
  545.    * Determine if monotonicity will be checked.
  546.    ***************************************************************************/
  547.  
  548.    if (recVary)
  549.      varyCount = 1;
  550.    else
  551.      varyCount = 0;
  552.  
  553.    for (i = 0; i < numDims; i++) if (dimVarys[i]) varyCount++;
  554.  
  555.    if (varyCount == 1)
  556.      checkMonotonicVar = TRUE;
  557.    else
  558.      checkMonotonicVar = FALSE;
  559.  
  560.    /***************************************************************************
  561.    * Read each record and calculate statistics.
  562.    ***************************************************************************/
  563.  
  564.    status = CDFlib (SELECT_, CDF_, id,
  565.                  VAR_, varN,
  566.                  CDF_DIMCOUNTS_, counts,
  567.             NULL_);
  568.    CHECKstatus (status);
  569.  
  570.    CALCstat (varMaxRec, NrecValues);
  571.  
  572.    if (rangeCheckVar) {
  573.      free (validmin);
  574.      free (validmax);
  575.    }
  576.  
  577.    if (filterFillsVar) free (fillval);
  578. }
  579.  
  580. /******************************************************************************
  581. * Close CDF and output file (if specified).
  582. ******************************************************************************/
  583.  
  584. status = CDFlib (SELECT_, CDF_, id,
  585.          CLOSE_, CDF_,
  586.          NULL_);
  587. CHECKstatus (status);
  588.  
  589. if (OUTfp != stdout) fclose (OUTfp);
  590.  
  591. Exit;
  592. }
  593.